class Parser {
  constructor() {
    // 匹配标题的正则表达式
    this.heading = /^(#{1,6}\s+)/;
    // 匹配引用区块的正则表达式
    this.blockQuote = /^(\>\s+)/;
    // 匹配无序列表的正则表达式
    this.unorderedList = /^((\*|-){1}\s+)/;
    // 匹配图片的正则表达式
    this.image = /\!\[(.*?)\]\((.*?)\)/g;
    // 匹配粗体文字的正则表达式
    this.strongText = /\*{2}(.*?)\*{2}/g;
    // 匹配代码行的正则表达式
    this.codeLine = /\`{1}(.*?)\`{1}/g;
    // TODO: 补充分割符正则
    // 匹配分隔符的正则表达式
    this.hr = /-{3,}/;
  }

  // 获取单行内容
  parseLineText(lineText) {
    this.lineText = lineText;
  }

  // 是否是空行
  isEmptyLine() {
    return this.lineText === "";
  }

  // 是否为符合标题规范
  isHeading() {
    return this.heading.test(this.lineText);
  }

  // 解析标题
  parseHeading() {
    const temp = this.lineText.split(" ");
    const headingLevel = temp[0].length;
    const title = temp[1].trim();
    return `<h${headingLevel}>${title}</h${headingLevel}>`;
  }

  /**
   * TODO: 请完成剩余各种语法的解析
   *   1. 完成对分隔符的解析
   *   2. 完成对引用区块的解析
   *   3. 完成对图片，和文字效果的解析
   *   4. 完成对无序列表的解析
   */
  // 判断当前行是否为hr标签
  isHr() {
    // 使用正则表达式匹配当前行文本
    return this.hr.test(this.lineText);
  }
  // 解析水平线
  parseHr() {
    // 返回水平线标签
    return "<hr>";
  }
  // 判断当前行是否为引用块
  isBlockQuote() {
    // 使用正则表达式匹配当前行是否为引用块
    return this.blockQuote.test(this.lineText);
  }
  // 解析引用块
  parseBlockQuote() {
    // 将文本按行分割
    const lines = this.lineText.split("\n");
    // 将每一行中的引用符号替换为空，并添加<p>标签，最后将所有行连接起来
    let temp = lines
      .map((line) => `<p>${line.replace(this.blockQuote, "").trim()}</p>`)
      .join("");
    // 将所有行包裹在<blockquote>标签中
    return `${temp}`;
  }
  // 判断当前行是否是无序列表
  isUnorderedList() {
    // 使用正则表达式判断当前行是否是无序列表
    return this.unorderedList.test(this.lineText);
  }
  // 解析无序列表
  parseUnorderedList() {
    // 将文本按行分割
    const lines = this.lineText.split("\n");
    // 将每一行文本替换掉无序列表符号，并添加<li>标签，最后将所有行连接起来
    let temp = lines
      .map((line) => `<li>${line.replace(this.unorderedList, "").trim()}</li>`)
      .join("");
    // 将所有行包裹在<ul>标签中
    return `${temp}`;
  }
  // 判断当前行是否为图片
  isImage() {
    // 使用正则表达式判断当前行是否为图片
    return this.image.test(this.lineText);
  }
  // 解析图片
  parseImage() {
    // 将图片替换为<img>标签
    return this.lineText.replace(this.image, `<img src="$2" alt="$1">`);
  }
  // 判断当前行文本是否为强文本
  isStrongText() {
    // 使用正则表达式判断当前行文本是否匹配强文本
    return (
      this.strongText.test(this.lineText) || this.codeLine.test(this.lineText)
    );
  }
  // 解析加粗文本
  parseStrongText() {
    // 将lineText中的strongText替换为<b>$1</b>
    this.lineText = this.lineText.replace(this.strongText, `<b>$1</b>`);
    return this.lineText.replace(this.codeLine, `<code>$1</code>`);
  }
  // 判断当前行是否为代码行
  // isCodeLine() {
  //   // 使用正则表达式匹配当前行文本
  //   return this.codeLine.test(this.lineText);
  // }
  // 解析代码行
  // parseCodeLine() {
  // 将代码行替换为带有<code>标签的代码行
  // return this.lineText.replace(this.codeLine, `<code>$1</code>`);
  // }
}

class Reader {
  constructor(text) {
    //获取全部原始文本
    this.text = text;
    this.lines = this.getLines();
    this.parser = new Parser();
  }

  runParser() {
    // 初始化当前行数为0
    let currentLine = 0;
    // 初始化已解析的数组
    let hasParsed = [];

    let n1 = 0;
    let n2 = 0;
    // 当未到达文件末尾时，继续解析
    while (!this.reachToEndLine(currentLine)) {
      // 获取行文本
      this.parser.parseLineText(this.getLineText(currentLine));

      // 判断空白行
      if (this.parser.isEmptyLine()) {
        // 如果是空白行，则跳过
        currentLine++;
        continue;
      }

      // 判断是否是标题
      if (this.parser.isHeading()) {
        // 如果是标题，则解析标题
        hasParsed.push(this.parser.parseHeading());
        // 解析完标题后，跳到下一行
        currentLine++;
        continue;
      }
      // TODO: 请完成剩余各种语法的解析
      // 判断是否是分割线
      if (this.parser.isHr()) {
        // 如果是分割线，则解析分割线
        hasParsed.push(this.parser.parseHr());
        // 解析完分割线后，跳到下一行
        currentLine++;
        continue;
      }
      // 判断是否是引用
      if (this.parser.isBlockQuote()) {
        if (n1 == 0) {
          hasParsed.push("<blockquote>");
          n1++;
        }
        // 如果是引用，则解析引用
        hasParsed.push(this.parser.parseBlockQuote());
        // 解析完引用后，跳到下一行
        currentLine++;
        this.parser.parseLineText(this.getLineText(currentLine));
        if (!this.parser.isBlockQuote()) {
          hasParsed.push("</blockquote>");
          n1 = 0;
        }
        continue;
      }
      // 判断是否是无序列表
      if (this.parser.isUnorderedList()) {
        if (n2 == 0) {
          hasParsed.push("<ul>");
          n2++;
        }
        // 如果是无序列表，则解析无序列表
        hasParsed.push(this.parser.parseUnorderedList());
        // 解析完无序列表后，跳到下一行
        currentLine++;
        this.parser.parseLineText(this.getLineText(currentLine));
        if (!this.parser.isUnorderedList()) {
          hasParsed.push("</ul>");
          n2 = 0;
        }
        continue;
      }
      // 判断是否是图片
      if (this.parser.isImage()) {
        // 如果是图片，则解析图片
        hasParsed.push(this.parser.parseImage());
        // 解析完图片后，跳到下一行
        currentLine++;
        continue;
      }
      // 判断是否是粗体文本
      if (this.parser.isStrongText()) {
        // 如果是粗体文本，则解析粗体文本
        hasParsed.push(this.parser.parseStrongText());
        // 解析完粗体文本后，跳到下一行
        currentLine++;
        continue;
      }
      // 判断是否是代码行
      // if (this.parser.isCodeLine()) {
      //   // 如果是代码行，则解析代码行
      //   hasParsed.push(this.parser.parseCodeLine());
      //   // 解析完代码行后，跳到下一行
      //   currentLine++;
      //   continue;
      // }
      // 如果以上都不是，则跳到下一行
      currentLine++;
    }
    // 返回已解析的字符串
    return hasParsed.join("");
  }

  getLineText(lineNum) {
    return this.lines[lineNum];
  }

  getLines() {
    this.lines = this.text.split("\n");
    return this.lines;
  }

  reachToEndLine(line) {
    return line >= this.lines.length;
  }
}

module.exports = function parseMarkdown(markdownContent) {
  return new Reader(markdownContent).runParser();
};
